package com.atguigu.tingshu.live.api;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.live.config.WebSocketLocalContainer;
import com.atguigu.tingshu.model.live.FromUser;
import com.atguigu.tingshu.model.live.SocketMsg;
import com.atguigu.tingshu.model.user.UserInfo;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;

import java.util.Map;

@Controller
@Slf4j
//websocket 接口的访问路径
@ServerEndpoint("/api/websocket/{roomId}/{token}")
public class WebSocketApiController {
    /*
        wb的初始化 比容器初始化对象要晚！不会从容器中装配对象
        解决： 可以通过 set方法注入给静态属性
     */
//    @Autowired
    static RedisTemplate redisTemplate;
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate){
        WebSocketApiController.redisTemplate = redisTemplate;
    }
    //标注的方法可以接收 ws访问/api/websocket/{roomId}/{token}地址的连接请求
    @OnOpen
    public void onOpen(Session session ,
                       @PathParam("roomId")Long roomId ,
                       @PathParam("token")String token){
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue()
                .get(RedisConstant.USER_LOGIN_KEY_PREFIX+token);
        log.info("接收到连接ws的请求，roomId:{} , token:{} , sessionId: {}" , roomId , token,session.getId());
        //将用户加入到直播间
        WebSocketLocalContainer.addUser2LiveRoom(session,roomId,userInfo);
        //发送消息
        SocketMsg msg = new SocketMsg();
        msg.setTime(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
        msg.setMsgType(SocketMsg.MsgTypeEnum.JOIN_CHAT.getCode());
        msg.setLiveRoomId(roomId);
        FromUser fromUser = new FromUser();
        fromUser.setUserId(userInfo.getId());
        fromUser.setNickname(userInfo.getNickname());
        fromUser.setAvatarUrl(userInfo.getAvatarUrl());
        msg.setFromUser(fromUser);
        String content = fromUser.getNickname() + " 进入了直播间";
        msg.setMsgContent(content);
        redisTemplate.convertAndSend("tingshu:live:message" ,
                msg);
//        WebSocketLocalContainer.sendMsg(roomId,msg);

    }
    //标注的方法 用来接收 建立连接成功的客户端 发送的消息
    @OnMessage
    public void onMessage(Session session ,@PathParam("roomId")Long roomId ,
                          @PathParam("token")String token,
                          String message){
        Map map = JSONObject.parseObject(message, Map.class);
        if(map.get("msgType").equals(SocketMsg.MsgTypeEnum.HEART_BEAT.getCode()) ||
                map.get("msgType").equals(SocketMsg.MsgTypeEnum.TOKEN_INVALID.getCode())){
            //心跳消息 和token无效消息 直接结束
            return;
        }
        redisTemplate.convertAndSend("tingshu:live:message" ,
                JSONObject.parseObject(message , SocketMsg.class) );
//        WebSocketLocalContainer.sendMsg(roomId , JSONObject.parseObject(message , SocketMsg.class) );
//        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue()
//                .get(RedisConstant.USER_LOGIN_KEY_PREFIX+token);
//        log.info("接收到客户端的请求，message:{} , sessionId:{} " , message,session.getId());
//
//        SocketMsg msg = new SocketMsg();
//        msg.setTime(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
//        msg.setMsgType(SocketMsg.MsgTypeEnum.PUBLIC_MSG.getCode());
//        msg.setLiveRoomId(roomId);
//        FromUser fromUser = new FromUser();
//        fromUser.setUserId(userInfo.getId());
//        fromUser.setNickname(userInfo.getNickname());
//        fromUser.setAvatarUrl(userInfo.getAvatarUrl());
//        msg.setFromUser(fromUser);
//        String content = fromUser.getNickname() + "说："+message;
//        msg.setMsgContent(content);
//        WebSocketLocalContainer.sendMsg(roomId , msg);

    }
    @OnClose
    public void onClose(Session session ,@PathParam("roomId")Long roomId ,
                        @PathParam("token")String token ){
        UserInfo userInfo = (UserInfo) redisTemplate.opsForValue()
                .get(RedisConstant.USER_LOGIN_KEY_PREFIX+token);
        log.info("接收到客户端断开连接的请求: roomId:{} , token:{} , sessionId:{} " , roomId,
                token,session.getId());
        WebSocketLocalContainer.removeUserFromLiveRoom(roomId , userInfo);

        SocketMsg msg = new SocketMsg();
        msg.setTime(new DateTime().toString("yyyy-MM-dd HH:mm:ss"));
        msg.setMsgType(SocketMsg.MsgTypeEnum.CLOSE_SOCKET.getCode());
        msg.setLiveRoomId(roomId);
        FromUser fromUser = new FromUser();
        fromUser.setUserId(userInfo.getId());
        fromUser.setNickname(userInfo.getNickname());
        fromUser.setAvatarUrl(userInfo.getAvatarUrl());
        msg.setFromUser(fromUser);
        String content = fromUser.getNickname() + " 退出直播间";
        msg.setMsgContent(content);
//        WebSocketLocalContainer.sendMsg(roomId , msg);
        redisTemplate.convertAndSend("tingshu:live:message" ,
                msg);
    }

    @OnError
    public void onError(Session session , Throwable e){
        log.error("连接异常，sessionId: {} , e: {}" , session.getId() , e.getMessage());
        e.printStackTrace();
    }
}
